#ifndef _IO_H_
#define _IO_H_

#include <stdint.h>

static inline void io_raw_writew(uint16_t val, volatile void *addr)
{
    asm volatile("strh %1, %0"
                 : : "Q"(*(volatile uint16_t *)addr), "r"(val));
}

static inline uint16_t io_raw_readw(const volatile void *addr)
{
    uint16_t val;
    asm volatile("ldrh %0, %1"
                 : "=r"(val)
                 : "Q"(*(volatile uint16_t *)addr));
    return val;
}
static inline void io_raw_writeb(uint8_t val, volatile void *addr)
{
    asm volatile("strb %1, %0"
                 : : "Qo"(*(volatile uint8_t *)addr), "r"(val));
}

static inline void io_raw_writel(uint32_t val, volatile void *addr)
{
    asm volatile("str %1, %0"
                 : : "Qo"(*(volatile uint32_t *)addr), "r"(val));
}

static inline uint8_t io_raw_readb(const volatile void *addr)
{
    uint8_t val;
    asm volatile("ldrb %0, %1"
                 : "=r"(val)
                 : "Qo"(*(volatile uint8_t *)addr));
    return val;
}

static inline uint32_t io_raw_readl(const volatile void *addr)
{
    uint32_t val;
    asm volatile("ldr %0, %1"
                 : "=r"(val)
                 : "Qo"(*(volatile uint32_t *)addr));
    return val;
}
#endif
